/*
	   _           _      _           _     _ 
	  (_)         | |    | |         (_)   | |
	   _ _   _ ___| |_ __| |_ __ ___  _  __| |
	  | | | | / __| __/ _` | '__/ _ \| |/ _` |
	  | | |_| \__ \ || (_| | | | (_) | | (_| |
	  | |\__,_|___/\__\__,_|_|  \___/|_|\__,_|
	 _/ |                                     
	|__/ 
	
	Copyright 2013 Caspar Isemer and and Eva Krueger, http://justdroid.org
	
	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at
	
		http://www.apache.org/licenses/LICENSE-2.0
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License. 
*/
//TODO: textmessage
package org.justdroid.justdroid;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class TextMessagesViewerApp extends JustDroidActivity {
	
	private Button btnReply, btnCall, btnDeleteThread;
	private final static int INBOX = 1;
	private final static int SENT = 2;
	private Cursor cursor;
	private Runnable runnable;
	private Handler handler;
	private HashMap<String, ArrayList<String>> records;
	private ArrayList<String> dateArrayList;
	private String address;
	private ProgressBar progressBar;
	
	void call() {
		//pass number to dialer app
		Intent intent = new Intent(getApplicationContext(), PhoneDialerApp.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.putExtra("call", TextMessagesViewerApp.this.address);
		startActivity(intent);
		finish();
	}
	
	void reply() {
		Intent intent = new Intent(getApplicationContext(), TextMessagesComposerApp.class);	 				
    	intent.putExtra("number", TextMessagesViewerApp.this.address);
    	HashMap<String, String> map = new ContactManager(getApplicationContext()).getNameFromNumber(TextMessagesViewerApp.this.address);
    	if(map.get("name") != null) {
    		intent.putExtra("name", map.get("name"));
    		intent.putExtra("type", map.get("type"));
    	}
    	startActivity(intent);
	}
	
	void attachKeyListener(Button button, final int buttonFlag) {
		button.setOnKeyListener(new OnKeyListener() {
			
			@Override
			public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
				if(keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
					switch(keyCode) {
					case KeyEvent.KEYCODE_DPAD_CENTER:
					case KeyEvent.KEYCODE_ENTER:
						switch(buttonFlag) {
						case 1:
							reply();
							break;
						case 2:
							call();
							break;
						case 3:
							confirmDelete("Are your sure you want to delete all the messages from this number?", 1, null);
				        	break;
						}
						break;
					}
				}
				return false;
			}
		});
	}
	
	private void confirmDelete(String message, final int deleteAll, final String dateTimestamp)
	 {
		if(TTS.isSpeaking())
			TTS.stop();
    	//giveFeedback(message);
	    AlertDialog confirmBox =new AlertDialog.Builder(this) 
	        //set message, title, and icon
	        .setTitle(getResources().getString(R.string.btnTextMsgsDelete)) 
	        .setMessage(message)
	        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {

	            public void onClick(DialogInterface dialog, int whichButton) {
	            	boolean success;
	            	if(deleteAll == 1) {
		            		success = deleteThread();
		            		if(success) {
		            			if(Utils.isAccessibilityEnabled(getApplicationContext()))
		            				TTS.speak(getResources().getString(R.string.deleteThreadSuccess));
								Toast.makeText(getApplicationContext(), getResources().getString(R.string.deleteThreadSuccess), Toast.LENGTH_SHORT).show();
								//reload activity
								finish();
								Intent intent = new Intent(getApplicationContext(), TextMessagesApp.class);
								intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
								startActivity(intent);
							}
							else
							{
								if(Utils.isAccessibilityEnabled(getApplicationContext()))
									TTS.speak(getResources().getString(R.string.deleteThreadFailure));
								Toast.makeText(getApplicationContext(), getResources().getString(R.string.deleteThreadFailure), Toast.LENGTH_SHORT).show();
							}
	            		}
	            	else {
	            		success = deleteMessage(dateTimestamp);
	            		if(success) {
	            			if(Utils.isAccessibilityEnabled(getApplicationContext()))
	            				TTS.speak(getResources().getString(R.string.deleteMessageSuccess));
							Toast.makeText(getApplicationContext(), getResources().getString(R.string.deleteMessageSuccess), Toast.LENGTH_SHORT).show();
							//reload activity
							finish();
							Intent intent = new Intent(getApplicationContext(), TextMessagesViewerApp.class);
							intent.putExtra("address", TextMessagesViewerApp.this.address);
							intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
							startActivity(intent);
						}
						else
						{
							if(Utils.isAccessibilityEnabled(getApplicationContext()))
								TTS.speak(getResources().getString(R.string.deleteMessageFailure));
							Toast.makeText(getApplicationContext(), getResources().getString(R.string.deleteMessageFailure), Toast.LENGTH_SHORT).show();
						}
	            	}
	                dialog.dismiss();
	            }
	        })
	        
	        .setNegativeButton("No", new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int which) {

	                dialog.dismiss();

	            }
	        })
	        .create();
	        confirmBox.show();
	 }
	
	/** Function to delete thread **/
	boolean deleteThread() {
		Uri deleteUri = Uri.parse("content://sms");
	    if(getContentResolver().delete(deleteUri, "address=?", new String[] {this.address}) != 0) {
	    	this.dateArrayList.clear();
	    	return true;
	    }
		return false;
	}
	
	/** Function to delete a message **/
	boolean deleteMessage(String dateTimestamp) { 
		Uri deleteUri = Uri.parse("content://sms");
		
	    if(getContentResolver().delete(deleteUri, "address=? AND date = ?", new String[] {this.address, dateTimestamp}) != 0)
	    	return true;
		return false;
	}
	
	private void markMessageRead(String dateTimestamp) {
		ContentValues values = new ContentValues();
        values.put("read", true);
        getContentResolver().update(Uri.parse("content://sms/inbox"), values, "address=? AND date = ?" , new String[] {this.address, dateTimestamp});                
	}
	
	/** Function to attach onTouchListener and onFocusListener to TextView **/
	void attachListenerToTextView(TextView textView) {
		final String text = textView.getText().toString();
		/*textView.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View view, MotionEvent arg1) {
				giveFeedback(text);
				return false;
			}
		});*/
		textView.setOnFocusChangeListener(new OnFocusChangeListener() {
			
			@Override
			public void onFocusChange(View view, boolean hasFocus) {
				if(hasFocus) {
					giveFeedback(text);
				}
			}
		});
	}
	
	/** Function to execute a thread to retrieve dialed call logs **/
	void runThread(final String address) {
		runnable = new Runnable() {
			@Override
			public void run() {
				getMessages(address);
			}
		};
		new Thread(runnable).start();
	}
	
	/** Function to retrieve messages **/
	@SuppressLint("SimpleDateFormat")
	void getMessages(String address) {
		ArrayList<String> values;
		Message message = new Message();
		Bundle bundle = new Bundle();
		String uri = "content://sms";
		/*switch(typeOfMessage) {
			case INBOX: uri = "content://sms/inbox";
				break;
			case SENT: uri = "content://sms/sent";
				break;
		}*/
		this.cursor = getContentResolver().query(Uri.parse(uri),  new String[] {"subject", "body", "type", "date"}, "address = ?", new String[]{address}, null);
		this.cursor.moveToFirst();
		do{
			values = new ArrayList<String>();
			try {
			//Date date = new Date(Long.valueOf(this.cursor.getString(this.cursor.getColumnIndex("date"))));
			String date = this.cursor.getString(this.cursor.getColumnIndex("date"));
			//SimpleDateFormat simpleDateFormat = new SimpleDateFormat("d MMMM yyyy' 'HH:MM:ss");
			//values.putString("date", Html.fromHtml("<br/>") + simpleDateFormat.format(date) + " ");
			values.add(this.cursor.getString(this.cursor.getColumnIndex("subject")));
			values.add(this.cursor.getString(this.cursor.getColumnIndex("body")));
			if(cursor.getString(cursor.getColumnIndex("type")).equalsIgnoreCase("1")){
			    // sms received
				values.add(Integer.toString(INBOX));
			 }
			 else if(cursor.getString(cursor.getColumnIndex("type")).equalsIgnoreCase("2")){
				 values.add(Integer.toString(SENT));
			 }
			records.put(date, values);
			}
			catch(Exception e) {
				continue;
			}
		}while(this.cursor.moveToNext() && this.cursor.getPosition() != this.cursor.getCount());
		if(cursor.getCount() > 0)
			bundle.putInt("status", 1);
		else
			bundle.putInt("status", 0);
		message.setData(bundle);
		handler.sendMessage(message);
	}
	
	/** Function to sort HashMap **/
    @SuppressLint("SimpleDateFormat")
	@SuppressWarnings("unchecked")
	void sort(@SuppressWarnings("rawtypes") HashMap hashMap) {
    	
    	Map<Integer, String> map = new TreeMap<Integer, String>(Collections.reverseOrder());
    	map.putAll(hashMap);
    	@SuppressWarnings("rawtypes")
		Set set = map.entrySet();
    	@SuppressWarnings("rawtypes")
		Iterator iterator = set.iterator();
    	while(iterator.hasNext()) {
            @SuppressWarnings("rawtypes")
			final
			Map.Entry me = (Map.Entry)iterator.next();
            
            this.dateArrayList.add(me.getKey().toString());
            progressBar.setVisibility(View.GONE);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
            params.setMargins(0, 0, 0, 100);
            
            //create TextViews
            final TextView txtMessage = new TextView(getApplicationContext());
            //display subject, body, date, type of message(sent or received)
            String text = "";
            if(records.get(me.getKey()).get(0) == null)
            	text = "";
            else
            	text = records.get(me.getKey()).get(0) + Html.fromHtml("<br/>");
            text += records.get(me.getKey()).get(1);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("d MMMM yyyy' 'HH:MM:ss");
            Date dateTemp = new Date(Long.valueOf(me.getKey().toString()));
        	String date = simpleDateFormat.format(dateTemp);
        	markMessageRead(me.getKey().toString());
            if(records.get(me.getKey()).get(2) == Integer.toString(INBOX)) {
        		text += Html.fromHtml("<br/>") + "Received on " + date;
        		 txtMessage.setGravity(Gravity.LEFT);
            }
            else {
            	text += Html.fromHtml("<br/>") + "Sent on " + date;
            	 txtMessage.setGravity(Gravity.RIGHT);
            }
            txtMessage.setWidth(params.width/3);
            txtMessage.setText(text);
            txtMessage.setContentDescription(text);
            txtMessage.setTextColor(getResources().getColor(R.color.card_textcolor_regular));
            txtMessage.setTextSize(getResources().getDimension(R.dimen.card_textsize_regular));
            txtMessage.setFocusable(true);
            txtMessage.setLayoutParams(params);
            
            attachListenerToTextView(txtMessage);
            
            //to delete the message
            txtMessage.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View view) {
					confirmDelete("Are you sure you want to delete this message?", 0, me.getKey().toString());
				}
			});
            
            txtMessage.setOnKeyListener(new OnKeyListener() {
				
				@Override
				public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
					if(keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
						switch(keyCode) {
						case KeyEvent.KEYCODE_DPAD_CENTER:
						case KeyEvent.KEYCODE_ENTER:
							confirmDelete("Are you sure you want to delete this message?", 0, me.getKey().toString());
							break;
						}
					}
					return false;
				}
			});
            
			LinearLayout layout = (LinearLayout)findViewById(R.id.textLinearLayout);
			layout.addView(txtMessage);
       }
    }
    
	/** Create the Text Messages Viewer activity **/
	@SuppressLint("HandlerLeak")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		setContentView(R.layout.textmessages_viewer);
		super.onCreate(savedInstanceState);
		
		/** Find UI elements **/
		btnReply = (Button) findViewById(R.id.btnTextMsgsReply);
		btnCall = (Button) findViewById(R.id.btnTextMsgsCall);
		btnDeleteThread = (Button) findViewById(R.id.btnTextMsgsDeleteThread);
		//get all contacts and pass to the list adapter
		progressBar = (ProgressBar) findViewById(R.id.progressBarMessages);
		progressBar.setVisibility(View.VISIBLE);
		
		/** attach onFocus and onTouch listeners **/
		attachListener(btnReply);
		attachListener(btnCall);
		attachListener(btnDeleteThread);
		
		this.address = getIntent().getExtras().getString("address");
		this.records = new HashMap<String, ArrayList<String>>();
		this.dateArrayList = new ArrayList<String>();
		
		attachKeyListener(btnReply, 1);
		
		/** If Reply button is pressed, open the Text Messages Composer to write a reply to this text message **/
		btnReply.setOnClickListener(new OnClickListener() {
	        public void onClick(View v) {        	
	        	reply();
	        }
	    });
		
		attachKeyListener(btnCall, 2);
		
		/** If Call button is pressed, call the sender of the text message **/
		btnCall.setOnClickListener(new View.OnClickListener() {
	        public void onClick(View v) {
	        	call();
	        }
	    });		
		
		attachKeyListener(btnDeleteThread, 3);
		
		/** If Delete button is pressed, bring up Yes/No dialog to confirm to delete this message **/
		btnDeleteThread.setOnClickListener(new View.OnClickListener() {
	        public void onClick(View v) {
	        	confirmDelete("Are your sure you want to delete all the messages from this number?", 1, null);
	        }
	    });		
		
		handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				//ArrayList<String> strRecords = new ArrayList<String>();
				//HashMap<String, String> record;
				Bundle bundle = message.getData();
				if(bundle.getInt("status") == 1) {
					//sort records on date
					sort(records);
				}
				else {
					//no messages from this number
					//finish();
				}
			}
		};
		
		/** Put most everything before here **/
	}	
	
	@Override
	public void onResume() {
		super.onResume();
		if(this.address != null) {
			if(Utils.isAccessibilityEnabled(getApplicationContext()))
				TTS.speak("Loading messages");
			Toast.makeText(getApplicationContext(), "Loading messages", Toast.LENGTH_SHORT).show();
			runThread(this.address);
			//runThread(SENT, this.address);
		}
		
		//get the root layout
		LinearLayout layout = (LinearLayout) findViewById(R.id.textmessagesviewer);
		Utils.applyFontColorChanges(getApplicationContext(), layout);  Utils.applyFontSizeChanges(getApplicationContext(), layout);  Utils.applyFontTypeChanges(getApplicationContext(), layout);
	}
}